classdef XDataStore < matlab.io.Datastore &...
                       matlab.io.datastore.MiniBatchable & ...
                       matlab.io.datastore.Shuffleable

    properties 
        MiniBatchSize
    end

    properties(SetAccess = protected)
        NumObservations
    end    
    properties (SetAccess = private)
        CurrentRowIndex  
        XTrain
        TTrain 
    end

    methods % begin methods section

        function ds = XDataStore(xtrain,ttrain)
            ds.CurrentRowIndex = 1;
            ds.XTrain = xtrain;
            ds.TTrain = ttrain;

            % Read labels from folder names
            numObservations = numel(ttrain);


            % Initialize datastore properties.
            ds.MiniBatchSize = 4;
            ds.NumObservations = numObservations;
            ds.CurrentRowIndex = 1;

        end


        function tf = hasdata(ds)
            % Return true if more data is available
            tf = ds.CurrentRowIndex + ds.MiniBatchSize - 1 ...
                <= ds.NumObservations;
        end


        function [data,info] = read(ds)
            % Read one mini-batch batch of data
            miniBatchSize = ds.MiniBatchSize;
            info = struct;

            remain = ds.NumObservations - ds.CurrentRowIndex + 1;
            if miniBatchSize > remain
                 miniBatchSize = remain
            end

            for i = 1:miniBatchSize
                predictors{i,1} = cell2mat(ds.XTrain(ds.CurrentRowIndex));
                responses(i,1) = ds.TTrain(ds.CurrentRowIndex);
                ds.CurrentRowIndex = ds.CurrentRowIndex + 1;
            end

            data = preprocessData(ds,predictors,responses);
        end

        function data = preprocessData(ds,predictors,responses)
            % data = preprocessData(ds,predictors,responses) preprocesses
            % the data in predictors and responses and returns the table
            % data

            % Pad data to length of longest sequence.

            % Return data as a table.
            data = table(predictors,responses);
        end

        function reset(ds)
            % Reset to the start of the data.

            ds.CurrentRowIndex = 1;
        end

        function dsNew = shuffle(ds)
            % dsNew = shuffle(ds) shuffles the files and the
            % corresponding labels in the datastore.

            % Create a copy of datastore
            dsNew = copy(ds);


            % Shuffle files and corresponding labels
            numObservations = dsNew.NumObservations;
            idx = randperm(numObservations);
            dsNew.XTrain = ds.XTrain(idx);
            dsNew.TTrain = ds.TTrain(idx);
        end
    end

    methods (Hidden = true)
        function frac = progress(myds)
            % Determine percentage of data read from datastore
            frac = (ds.CurrentRowIndex - 1) / ds.NumObservations;
        end
    end



end
